#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
'''
@File    :   ascvd.py
@Time    :   2020/11/25
@Author  :   wenke wang
@Version :   1.0
@Desc    :   ASCVD风险评估模型
'''

# here put the import lib
import math
from decimal import Decimal
from ascvd_eval_param import AscvdEvalParam


def evaluate(param, eval_type="tc"):
    """
    评估
    """
    # 极高危直接返回
    if param.ascvd or param.cvd:
        return { "veryHighRisk": True }

    risk10 = eevaluate10_ldlc(param) if eval_type == "ldlc" else evaluate10_tc(param)
    if risk10["risk10"] != "high" and param.age >= 20 and param.age <= 59:
        risk85 = evaluate85(param)
        risk10.update(risk85)
    return risk10

def eevaluate10_ldlc(param):
    """
    基于LDL-C进行10年风险评估
    """
    ln_age = math.log(param.age)
    ln_sbp = math.log(param.sbp)
    ln_ldlc = math.log(param.ldlc)
    ln_hdlc = math.log(param.hdlc)
    if param.gender == "M":
        S10 = 0.971  
        MeanXB = 161.703
        IndexXB = 36.216 * ln_age + 7.959 * ln_ldlc - 0.265 * ln_hdlc + 22.768 * ln_sbp + 0.480 * param.smoking + 0.236 * param.dm - 4.828 * ln_age * ln_sbp - 1.903 * ln_age * ln_ldlc        
    else: 
        S10 = 0.984
        MeanXB = 191.923
        IndexXB = 46.143 * ln_age + 0.127 * ln_ldlc - 0.531 * ln_hdlc + 37.045 * ln_sbp + 0.091 * param.smoking + 0.518 * param.dm - 8.757 * ln_age * ln_sbp

    P = 1 - S10 ** math.exp(IndexXB - MeanXB)
    P = Decimal(P).quantize(Decimal("0.00"))
    res = { "score10": str(P) }
    if P < Decimal("0.05"):
        res["risk10"] = "low"
    elif P < Decimal("0.10"):
        res["risk10"] = "middle"
    else:
        res["risk0"] = "high"
    return res

def evaluate10_tc(param):
    """
    基于TC进行10年风险评估
    """
    ln_age = math.log(param.age)
    ln_sbp = math.log(param.sbp)
    ln_tc = math.log(param.tc)
    ln_hdlc = math.log(param.hdlc)
    if param.gender == "M":
        S10 = 0.971  
        MeanXB = 191.613
        IndexXB = 43.321 * ln_age + 13.022 * ln_tc - 0.411 * ln_hdlc + 22.684 * ln_sbp + 0.474 * param.smoking + 0.223 * param.dm - 4.812 * ln_age * ln_sbp - 3.075 * ln_age * ln_tc        
    else: 
        S10 = 0.984
        MeanXB = 192.086
        IndexXB = 45.905 * ln_age + 0.392 * ln_tc - 0.603 * ln_hdlc + 36.897 * ln_sbp + 0.090 * param.smoking + 0.510 * param.dm - 8.723 * ln_age * ln_sbp

    P = 1 - S10 ** math.exp(IndexXB - MeanXB)
    P = Decimal(P).quantize(Decimal("0.00"))
    res = { "score10": str(P) }
    if P < Decimal("0.05"):
        res["risk10"] = "low"
    elif P < Decimal("0.10"):
        res["risk10"] = "middle"
    else:
        res["risk0"] = "high"
    return res

def evaluate85(param):
    """
    对个体终生(至85岁)首次发生心血管病的风险进行评估
    """
    risk_score = 0    
    risk_score = risk_score + (1 if param.sbp > 159 or param.dbp > 119 else 0)
    risk_score = risk_score + (1 if param.tc > Decimal(200) or param.ldlc > Decimal(200) else 0)
    risk_score = risk_score + (1 if param.hdlc < Decimal(40) else 0)
    risk_score = risk_score + (1 if param.bmi >= Decimal("28.00") else 0)
    risk_score = risk_score + param.smoking
    
    return { "risk85": "low" if risk_score < 2 else "high" }


if __name__ == "__main__":
    param = AscvdEvalParam(37, "M", 170, 58, 0, 0, 0, 1, 139, 85, 200, 80, 120)
    # result = evaluate(param)
    result = evaluate(param, eval_type="ldlc")
    print(result)